﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Web.Mvc;

namespace QuickApp.MVCControl.FlexiGrid
{
    /// <summary>
    /// 表格的列信息集合类
    /// </summary>
    /// <typeparam name="T">对象类型</typeparam>
    public class FlexiGridColumnCollection<T> : ICollection<FlexiGridColumn> where T : class
    {
        #region Private fields
        /// <summary>
        /// 列信息集合
        /// </summary>
        private readonly IList<FlexiGridColumn> _columns = null;
        private readonly object _ModelInstance = null;

        #endregion

        public FlexiGridColumnCollection()
        {
            _ModelInstance = Activator.CreateInstance(typeof(T));
            _columns = new List<FlexiGridColumn>();
        }

        #region Bind

        /// <summary>
        /// 绑定对象属性到表格字段
        /// </summary>
        /// <param name="action">对象属性的lambda表达式</param>
        /// <param name="title">标题</param>
        /// <param name="width">宽度</param>
        /// <param name="sortable"></param>
        /// <returns></returns>
        public FlexiGridColumnSettings Bind(Expression<Func<T, object>> action, string title, int width, bool sortable)
        {
            return Bind(action).Title(title).Width(width).Sortable();
        }

        /// <summary>
        /// 绑定对象属性到表格字段
        /// </summary>
        /// <param name="action">对象属性的lambda表达式</param>
        /// <param name="title">标题</param>
        /// <param name="width">宽度</param>
        /// <returns></returns>
        public FlexiGridColumnSettings Bind(Expression<Func<T, object>> action, string title, int width)
        {
            return Bind(action).Title(title).Width(width);
        }

        /// <summary>
        /// 绑定对象属性到表格字段
        /// </summary>
        /// <param name="action">对象属性的lambda表达式</param>
        /// <param name="title">标题</param>
        /// <returns></returns>
        public FlexiGridColumnSettings Bind(Expression<Func<T, object>> action, string title)
        {
            return Bind(action).Title(title);
        }

        /// <summary>
        /// 绑定对象属性到表格字段
        /// </summary>
        /// <param name="action">对象属性的lambda表达式</param>
        /// <returns></returns>
        public FlexiGridColumnSettings Bind(Expression<Func<T, object>> action)
        {
            var expression = action.Body.RemoveUnary() as MemberExpression;
            if (expression == null)
            {
                throw new ArgumentException("非法的使用Bind方法，当前表达式不可解析");
            }

            // 获取标题
            string title = string.Empty;

            try
            {
                var metadata = ModelMetadata.FromStringExpression(expression.Member.Name, new ViewDataDictionary(_ModelInstance));
                title = metadata.DisplayName ?? metadata.PropertyName;
            }
            catch (Exception ex)
            {
                // 记录日志
            }
            return Bind(expression.Member.Name, title);
        }

        /// <summary>
        /// 绑定对象属性到表格字段
        /// </summary>
        /// <param name="bindField">字段名称</param>
        /// <param name="title">标题</param>
        /// <param name="width">宽度</param>
        /// <param name="sortable">是否可以排序</param>
        /// <returns></returns>
        public FlexiGridColumnSettings Bind(string bindField, string title, int width, bool sortable)
        {
            return Bind(bindField).Title(title).Width(width).Sortable(sortable);
        }

        /// <summary>
        /// 绑定对象属性到表格字段
        /// </summary>
        /// <param name="bindField">字段名称/param>
        /// <param name="title">标题</param>
        /// <param name="width">宽度</param>
        /// <returns></returns>
        public FlexiGridColumnSettings Bind(string bindField, string title, int width)
        {
            return Bind(bindField).Title(title).Width(width);
        }

        /// <summary>
        /// 绑定对象属性到表格字段
        /// </summary>
        /// <param name="bindField">字段名称</param>
        /// <param name="title">标题</param>
        /// <returns></returns>
        public FlexiGridColumnSettings Bind(string bindField, string title)
        {
            return Bind(bindField).Title(title);
        }

        /// <summary>
        /// 绑定对象属性到表格字段
        /// </summary>
        /// <param name="bindField">字段名称</param>
        /// <returns></returns>
        public FlexiGridColumnSettings Bind(string bindField)
        {
            var column = new FlexiGridColumn(bindField);
            this._columns.Add(column);
            return column.ColumnSettings;
        }

        #endregion

        #region Implementation of IEnumerable

        public IEnumerator<FlexiGridColumn> GetEnumerator()
        {
            return this._columns.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        #endregion

        #region Implementation of ICollection<FlexiGridColumn>

        public void Add(FlexiGridColumn item)
        {
            this._columns.Add(item);
        }

        public void Clear()
        {
            this._columns.Clear();
        }

        public bool Contains(FlexiGridColumn item)
        {
            return this._columns.Contains(item);
        }

        public void CopyTo(FlexiGridColumn[] array, int arrayIndex)
        {
            this._columns.CopyTo(array, arrayIndex);
        }

        public bool Remove(FlexiGridColumn item)
        {
            return this._columns.Remove(item);
        }

        public int Count
        {
            get { return this._columns.Count; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        #endregion
    }
}